package com.gitee.cui.basic.innerlock;

import com.gitee.cui.util.ByteUtil;
import lombok.extern.slf4j.Slf4j;
import org.openjdk.jol.info.ClassLayout;

/**
 * 锁对象接口分析类
 * @author cuiqingqiang
 * @version 1.0
 * @date 2021/11/19 15:30
 **/
@Slf4j
public class ObjectLock {

    private Integer amount = 0;

    public void increase() {
        synchronized (this) {
            amount++;
        }
    }

    public Integer getAmount() {
        return amount;
    }

    /**
     * 输出16进制的hashCode
     * @return 16进制的hashCode
     */
    public String originHexHash() {
        // 对象原始hashCode
        int hashCode = this.hashCode();
        // 将二进制转换为十六进制字符串
        return Integer.toHexString(hashCode);
    }

    /**
     * 输出二进制的hashCode
     * @return 二进制的hashCode
     */
    public String originBinaryHash() {
        // 对象原始hashCode
        int hashCode = this.hashCode();
        // 将原始hashCode转换为小端模式
        byte[] bytes = String.valueOf(hashCode).getBytes();
        // 转换成二进制字符串
        StringBuffer sb = new StringBuffer();
        for (byte b : bytes) {
            sb.append(ByteUtil.byte2BinaryString(b));
            sb.append(" ");
        }
        return sb.toString();
    }

    /**
     * 输出16进制，小端模式的hashCode
     * @return 16进制，小端模式的hashCode
     */
    public String hexHash() {
        // 对象原始hashCode
        int hashCode = this.hashCode();
        // 将原始hashCode转换为小端模式
        byte[] bytes = ByteUtil.int2Bytes_LE(hashCode);
        // 将二进制转换为十六进制字符串
        return ByteUtil.byteToHex(bytes);
    }

    /**
     * 输出二进制，小端模式的hashCode
     * @return 二进制，小端模式的hashCode
     */
    public String binaryHash() {
        // 对象原始hashCode
        int hashCode = this.hashCode();
        // 将原始hashCode转换为小端模式
        byte[] bytes = ByteUtil.int2Bytes_LE(hashCode);
        // 转换成二进制字符串
        StringBuffer sb = new StringBuffer();
        for (byte b : bytes) {
            sb.append(ByteUtil.byte2BinaryString(b));
            sb.append(" ");
        }
        return sb.toString();
    }

    /**
     * 输出16进制，小端模式的threadId
     * @return 16进制，小端模式的threadId
     */
    public String hexThreadId() {
        // 当前线程原始id
        long threadId = Thread.currentThread().getId();
        // 将原始线程原始id转换为小端模式
        byte[] bytes = ByteUtil.long2bytes_LE(threadId);
        // 将二进制转换为十六进制字符串
        return ByteUtil.byteToHex(bytes);
    }

    /**
     * 输出二进制，小端模式的threadId
     * @return 二进制，小端模式的threadId
     */
    public String binaryThreadId() {
        // 当前线程原始id
        long threadId = Thread.currentThread().getId();
        // 将原始线程原始id转换为小端模式
        byte[] bytes = ByteUtil.long2bytes_LE(threadId);
        // 转换成二进制字符串
        StringBuffer sb = new StringBuffer();
        for (byte b : bytes) {
            sb.append(ByteUtil.byte2BinaryString(b));
            sb.append(" ");
        }
        return sb.toString();
    }

    /**
     * 打印出结构信息
     */
    public void printSelf() {
        log.info("lock hexHash= {}", hexHash());
        log.info("lock binaryHash= {}", binaryHash());
        log.info("lock originHexHash= {}", originHexHash());
        // 通过JOL工具获取this的对象布局
        String printable = ClassLayout.parseInstance(this).toPrintable();
        // 输出对象布局
        log.info("lock= {}", printable);
    }

    /**
     * 打印出对象结构
     */
    public void printObjectStruct() {
        String printable = ClassLayout.parseInstance(this).toPrintable();
        log.info("lock= {}", printable);
    }
}
